﻿#include "MeasureView/MeasureDots2Line.h"
#include "MeasureView/UnitConvert.h"
#include "MeasureView/MeasureDataSet.h"
#include <QDebug>
#include <QtMath>
namespace Qly {

MeasureDots2Line::MeasureDots2Line(MeasureDataSet *parent)
    :MeasureElement(parent)
{
    m_measureType = Dots2Line;
    m_keyPoints_pix.resize(2);
    m_keyPoints_um.resize(2);
    m_textTemplate = parent->m_textTemplate_MeasureDot2Line;
}

double dist(QPointF p1, QPointF p2)
{
    QPointF t = p2 - p1;
    return hypot(t.x(), t.y());
}

QPointF MeasureDots2Line::endPoint(QPointF lineS, QPointF lineE, QPointF p)
{
    //计算直线外一点在直线上的垂足
    //点P(X,Y)在直线Ax+By+C=0上的垂足为
    //x=(B*B*X-A*B*Y-A*C)/(A*A+B*B)
    //y=(-A*B*X+A*A*Y-B*C)/(A*A+B*B)
    //直线公式(x-x1)/(x2-x1)=(y-y1)/(y2-y1)--》(y2-y1)x+(x1-x2)y-x1(y2-y1)+y1(x2-x1)=0
    double A = lineE.y() - lineS.y();
    double B = lineS.x() - lineE.x();
    double C = - lineS.x() * A - lineS.y() * B;
    double x = (B * B * p.x()- A * B * p.y() - A * C)/(A * A + B * B);
    double y = (-A * B * p.x() + A * A  * p.y() - B * C) / (A * A + B * B);

    return QPointF(x, y);
}

MeasureElement::DeleteResult MeasureDots2Line::tryDelete(QPointF p)
{
    int N = m_textBlocks.size();
    for(int i = 0; i < N; i++)
    {
        if(m_textBlocks[i].contains(p.toPoint()))
        {
            m_keyPoints_pix.removeAt(2 + 2 * i + 1);
            m_keyPoints_pix.removeAt(2 + 2 * i);
            m_keyPoints_um.removeAt(2 + 2 * i + 1);
            m_keyPoints_um.removeAt(2 + 2 * i);

            m_results_pix.removeAt(i);
            m_results_um.removeAt(i);

            m_textBlocks.removeAt(i);
            updateText(true);
            if(N == 1) // 说明就一个测点，还被删了。需要删除这个对象。
            {
                return DeleteByOther;
            }
            return DeleteByMyself; // 内部已经删除完了，不需要外部处理
        }
    }
    return DeleteNothing; //到这里说明没找到
}
int MeasureDots2Line::mouseRButtonPress(QPointF point_pix, QPointF point_um)
{
    if(m_measureState == DS_STATE2)
    {
        m_keyPoints_pix.push_back(point_pix);
        m_keyPoints_um.push_back(point_um);

        QPointF p_pix = endPoint(m_keyPoints_pix[0], m_keyPoints_pix[1], point_pix);
        QPointF p_um = endPoint(m_keyPoints_um[0], m_keyPoints_um[1], point_um);
        m_keyPoints_pix.push_back(p_pix);
        m_keyPoints_um.push_back(p_um);

        m_results_pix.push_back(dist(point_pix, p_pix));
        m_results_um.push_back(dist(point_um, p_um));

//        ++s_id;

        updateText(true);
//        compute();
        m_measureState = DS_FINISH;
    }
    //m_measureState = DS_ERROR;
    return m_measureState;
}

void MeasureDots2Line::textMove(const QPointF &offset_pix, const QPointF &offset_um)
{
    Q_UNUSED(offset_um);
    if(m_pTextBlock)
    {
        m_pTextBlock->translate(offset_pix, offset_um);
    }
}


bool MeasureDots2Line::isInTextBox(const QPointF &point)
{
    int N = m_textBlocks.size();
    for(int i= 0; i < N; i++)
    {
        if(m_textBlocks[i].contains(point.toPoint()) )
        {
            m_pTextBlock = &(m_textBlocks[i]);
            return true;
        }
    }
    m_pTextBlock = nullptr;
    return false;
}

void MeasureDots2Line::updateText(bool updatePosition)
{
    int N = m_results_um.size();
    m_textBlocks.resize(N);
    for(int i = 0; i < N; i++)
    {
        QString text = m_textTemplate;
        QString lenStr, unitStr;
//        unit.convert(UnitConvert::um, m_results_um[i], UnitConvert::autoLengthUnit, lenStr, unitStr);
//        text.replace("@length", lenStr, Qt::CaseSensitive);
//        text.replace("@unit", unitStr, Qt::CaseSensitive);
        m_pParent->m_unitConvert_MeasureDot2Line.replaceLength(text, m_results_um[i], "@length", "@unit");

        QString pid = QString::number(1 + i);
        text.replace("@pid", pid, Qt::CaseSensitive);
        //QString id = QString::number(m_id + i);
        QString id = QString("%1.%2").arg(m_id).arg(i + 1);
        text.replace("@id", id, Qt::CaseSensitive);

        m_textBlocks[i].setPen(m_pen);
        m_textBlocks[i].setFont(m_font);
        m_textBlocks[i].setText(text);
        if(updatePosition)
        {

            m_textBlocks[i].moveTo((m_keyPoints_pix[2 * i + 3] + m_keyPoints_pix[2 * i + 2] ) / 2.0,
                    (m_keyPoints_um[2 * i + 3] + m_keyPoints_um[2 * i + 2] ) / 2.0);
        }
    }
}


int MeasureDots2Line::mouseMove(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_STATE2 )
    {
        m_tempPoint_pix[0] = point_pix;
        m_tempPoint_um[0] = point_um;

        QPointF p_pix = endPoint(m_keyPoints_pix[0], m_keyPoints_pix[1], point_pix);
        QPointF p_um = endPoint(m_keyPoints_um[0], m_keyPoints_um[1], point_um);
        m_tempPoint_pix[1] = p_pix;
        m_tempPoint_um[1] = p_um;
    }
    return m_measureState;
}

int MeasureDots2Line::setPixelSize(double newPixelSize_um, int method)
{
    if(m_keyPoints_pix.size() != m_keyPoints_um.size()) //这里表示出现了错误，也应该退出
    {
        qWarning() << "MeasureDots2Line::setLens(). ERROR: m_keyPoints_pix.size() != m_keyPoints_um.size()";
        return 0;
    }
    if(newPixelSize_um == 0.0)
    {
        qWarning() << "newPixelSize_um = 0";
        return 0;
    }
    if(method == 0)//只更新长度的数值，图元在图像上的位置不变
    {
        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
        {
            m_keyPoints_um[i] = m_keyPoints_pix[i] * newPixelSize_um;
        }
    }
    else
    {
//        LensData & oldData = lens.lensByIndex(oldLens);
//        LensData & newData = lens.currentLens();
//        double dx = (newData.xCompensate_um - oldData.xCompensate_um);
//        double dy = (newData.yCompensate_um - oldData.yCompensate_um);
        for(int  i = 0; i < m_keyPoints_pix.size(); ++i)
        {
            m_keyPoints_pix[i] = (m_keyPoints_um[i] /*+ QPointF(dx, dy)*/) / newPixelSize_um;
        }
    }
//    compute();
    updateText();
    return 1;
}


void MeasureDots2Line::paint(QPainter &painter)
{
    if( m_measureState != DS_IDLE )
    {
        painter.save();
        painter.setPen(m_pen);

        if(m_measureState == DS_STATE1)
        {
            drawCross(painter, m_keyPoints_pix[0]);
        }
        if(m_measureState == DS_STATE2)
        {
            drawCross(painter, m_keyPoints_pix[0]);
            drawCross(painter, m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);

            //double angle = m_angle > 0? m_angle -90.0 : m_angle + 90.0;
            int N = m_keyPoints_pix.size();
            for(int i = 2; i < N; i += 2)
            {
                drawCross(painter, m_keyPoints_pix[i]);
                painter.drawLine(m_keyPoints_pix[i], m_keyPoints_pix[i + 1]);
               // painter.setFont(m_font);
               // painter.drawText(m_textBoxs[i], m_texts[i]);

            }
            //qDebug() << m_tempPoint_pix[0] << m_tempPoint_pix[1];
            painter.drawLine(m_tempPoint_pix[0], m_tempPoint_pix[1]);
            for(int i = 0; i < m_textBlocks.size(); i++)
            {
                m_textBlocks[i].draw(painter);
            }
        }
        if(m_measureState == DS_FINISH)
        {
            drawCross(painter, m_keyPoints_pix[0]);
            drawCross(painter, m_keyPoints_pix[1]);
            painter.drawLine(m_keyPoints_pix[0], m_keyPoints_pix[1]);
            double angle = m_angle > 0? m_angle -90.0 : m_angle + 90.0;
            int N = m_keyPoints_pix.size();
            for(int i = 2; i < N; i += 2)
            {
                drawCross(painter, m_keyPoints_pix[i]);
                painter.drawLine(m_keyPoints_pix[i], m_keyPoints_pix[i + 1]);
               // painter.setFont(m_font);
               // painter.drawText(m_textBoxs[i], m_texts[i]);
            }
            for(int i = 0; i < m_textBlocks.size(); i++)
            {
                m_textBlocks[i].draw(painter);
                if(&(m_textBlocks[i]) == m_pTextBlock)
                {
                    QPointF p = m_pTextBlock->anchorPoint();
                    QPen pen = m_pen;
                    pen.setStyle(Qt::DashDotLine);
                    painter.setPen(pen);
                    painter.drawLine(p, m_keyPoints_pix[2 * i + 2]);
                    painter.setPen(m_pen);
                }
            }
        }
        painter.restore();
    }
}

int MeasureDots2Line::mouseLButtonRelease(QPointF point_pix, QPointF point_um)
{
    if(m_measureState == DS_FINISH)
    {
        m_pTextBlock = nullptr;
        return 1;
    }
    return 0;
}

void MeasureDots2Line::resume()
{
    if(m_keyPoints_pix.size() >= 2)
    {
        m_measureState = DS_STATE2;
    }
}

int MeasureDots2Line::mouseLButtonPress(QPointF point_pix, QPointF point_um)
{
    if( m_measureState == DS_IDLE )
    {
        m_keyPoints_pix[0] = point_pix;
        m_keyPoints_um[0] = point_um;
        m_measureState = DS_STATE1;
    }
    else if(m_measureState == DS_STATE1)
    {
        m_keyPoints_pix[1] = point_pix;
        m_keyPoints_um[1] = point_um;

        QPointF p = m_keyPoints_pix[1] - m_keyPoints_pix[0]; //
        m_angle = atan2(p.y(), p.x()) * 180.0 / M_PI;
        m_measureState = DS_STATE2;
    }
    else if(m_measureState == DS_STATE2)
    {
        m_keyPoints_pix.push_back(point_pix);
        m_keyPoints_um.push_back(point_um);

        QPointF p_pix = endPoint(m_keyPoints_pix[0], m_keyPoints_pix[1], point_pix);
        QPointF p_um = endPoint(m_keyPoints_um[0], m_keyPoints_um[1], point_um);
        m_keyPoints_pix.push_back(p_pix);
        m_keyPoints_um.push_back(p_um);

        m_results_pix.push_back(dist(point_pix, p_pix));
        m_results_um.push_back(dist(point_um, p_um));

//        ++ s_id;
        updateText(true);
    }
    return m_measureState;
}

void MeasureDots2Line::compute()
{

}


}
